{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import arcpy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "sr = arcpy.SpatialReference(4326)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "pt_tam = arcpy.PointGeometry(inputs=arcpy.Point(116.403927,39.915087),\n",
    "spatial_reference=sr)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 投影转换方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "p_pt_tam = pt_tam.projectAs(spatial_reference=arcpy.SpatialReference(3857))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'POINT (12958025.879977388 4853610.6152063264)'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p_pt_tam.WKT"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on method projectAs in module arcpy.arcobjects.arcobjects:\n",
      "\n",
      "projectAs(spatial_reference, transformation_name=None) method of arcpy.arcobjects.geometries.PointGeometry instance\n",
      "    Geometry.projectAs(spatial_reference, {transformation_name})\n",
      "    \n",
      "    Projects a geometry and optionally applies a geotransformation.\n",
      "    \n",
      "    To project, the geometry needs to have a spatial reference, and not\n",
      "    have an UnknownCoordinateSystem . The new spatial reference system\n",
      "    passed to the method defines the output coordinate system. If either\n",
      "    spatial reference is unknown the coordinates will not be changed. The\n",
      "    Z- and measure values are not changed by the ProjectAs method.\n",
      "    \n",
      "      spatial_reference(SpatialReference):\n",
      "    The new spatial reference.\n",
      "    This can be a SpatialReference object or the coordinate system name.\n",
      "    \n",
      "      transformation_name{String}:\n",
      "    The geotransformation name.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(pt_tam.projectAs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 坐标系记法转换"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "|十进制度\t\t|DD\t|39.91508700N 116.40392700E\t|\n",
      "|十进制度分\t\t|DDM\t|39 54.90522000N 116 24.23562000E\t|\n",
      "|度分秒\t\t\t|DMS\t|39 54 54.31320000N 116 24 14.13720000E\t|\n",
      "|全球区域参考系\t\t|GARS\t|593LV25\t|\n",
      "|世界地理参考系\t\t|GEOREF\t|VJMK2423562054905220\t|\n",
      "|(美)军事格网参考系\t|MGRS\t|50SMK4905625618502813\t|\n",
      "|(美)国家格网\t\t|USNG\t|50S MK 49056256 18502813\t|\n",
      "|通用横轴墨卡托投影\t|UTM\t|50S 449056 4418502\t|\n",
      "|通用横轴墨卡托(无空格)\t|UTMNS\t|50N4490564418502\t|\n"
     ]
    }
   ],
   "source": [
    "print(f\"|十进制度\\t\\t|DD\\t|{pt_tam.toCoordString('DD')}\\t|\")\n",
    "print(f\"|十进制度分\\t\\t|DDM\\t|{pt_tam.toCoordString('DDM')}\\t|\")\n",
    "print(f\"|度分秒\\t\\t\\t|DMS\\t|{pt_tam.toCoordString('DMS')}\\t|\")\n",
    "print(f\"|全球区域参考系\\t\\t|GARS\\t|{pt_tam.toCoordString('GARS')}\\t|\")\n",
    "print(f\"|世界地理参考系\\t\\t|GEOREF\\t|{pt_tam.toCoordString('GEOREF')}\\t|\")\n",
    "print(f\"|(美)军事格网参考系\\t|MGRS\\t|{pt_tam.toCoordString('MGRS')}\\t|\")\n",
    "print(f\"|(美)国家格网\\t\\t|USNG\\t|{pt_tam.toCoordString('USNG')}\\t|\")\n",
    "print(f\"|通用横轴墨卡托投影\\t|UTM\\t|{pt_tam.toCoordString('UTM')}\\t|\")\n",
    "print(f\"|通用横轴墨卡托(无空格)\\t|UTMNS\\t|{pt_tam.toCoordString('UTMNS')}\\t|\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### FromCoordString 方法 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "pt = arcpy.FromCoordString(coordinate_str=\"\\\n",
    "    39 54 54.31320000N \\\n",
    "    116 24 14.13720000E\",\n",
    "notation=\"DMS\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'POINT (116.40392700000001 39.915087)'"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pt.WKT"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### getGeohash方法：获取Geohash字符串"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* GeoHash一般实用长度范围是在1-11位之间,精度越高，位数越长，范围越小。\n",
    "* 到了11位长度，就已经是厘米级，所以在细已经没有多大实用价值了。\n",
    "* ArcGIS/GeoSecen提供的方法提供了1-20位之间的geohash字符串编码能力，默认精度是8"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'wx4g0f6f'"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pt_tam.getGeohash()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "length = 1\tw\n",
      "length = 2\twx\n",
      "length = 3\twx4\n",
      "length = 4\twx4g\n",
      "length = 5\twx4g0\n",
      "length = 6\twx4g0f\n",
      "length = 7\twx4g0f6\n",
      "length = 8\twx4g0f6f\n",
      "length = 9\twx4g0f6f0\n",
      "length = 10\twx4g0f6f0p\n",
      "length = 11\twx4g0f6f0pd\n",
      "length = 12\twx4g0f6f0pdb\n",
      "length = 13\twx4g0f6f0pdbq\n",
      "length = 14\twx4g0f6f0pdbqw\n",
      "length = 15\twx4g0f6f0pdbqw7\n",
      "length = 16\twx4g0f6f0pdbqw79\n",
      "length = 17\twx4g0f6f0pdbqw79z\n",
      "length = 18\twx4g0f6f0pdbqw79zq\n",
      "length = 19\twx4g0f6f0pdbqw79zq3\n",
      "length = 20\twx4g0f6f0pdbqw79zq3d\n"
     ]
    }
   ],
   "source": [
    "for i in range(1,21):\n",
    "    print(f\"length = {i}\\t{pt_tam.getGeohash(i)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### FromGeohash方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>table td#td0  {font-weight: bold}</style><table class=\"notebook\"><colgroup><col style=\"width:45%\"></col><col style=\"width:55%\"></col></colgroup><tr><td id = \"td0\" title=\"XMin (Left)\">XMin (Left)</td><td title=\"116.403923\">116.403923</td></tr><tr><td id = \"td0\" title=\"XMax (Right)\">XMax (Right)</td><td title=\"116.404266\">116.404266</td></tr><tr><td id = \"td0\" title=\"YMin (Bottom)\">YMin (Bottom)</td><td title=\"39.915047\">39.915047</td></tr><tr><td id = \"td0\" title=\"YMax (Top)\">YMax (Top)</td><td title=\"39.915218\">39.915218</td></tr></table><div class=\"title\"><i class=\"chevron-open\" onClick=\"event.preventDefault();document.getElementById('DCFE9200-A2A9-4905-B48C-CF11DD78AEB6').style.display =   document.getElementById('DCFE9200-A2A9-4905-B48C-CF11DD78AEB6').style.display == 'none' ? 'block' : 'none';this.classList.toggle('chevron-closed');\"></i>spatialReference</div><div id=\"DCFE9200-A2A9-4905-B48C-CF11DD78AEB6\"><style>table td#td0  {font-weight: bold}</style><table class=\"notebook\"><colgroup><col style=\"width:45%\"></col><col style=\"width:55%\"></col></colgroup><tr><td id = \"td0\" title=\"name (Geographic Coordinate System)\">name (Geographic Coordinate System)</td><td title=\"GCS_WGS_1984\">GCS_WGS_1984</td></tr><tr><td id = \"td0\" title=\"factoryCode (WKID)\">factoryCode (WKID)</td><td title=\"4326\">4326</td></tr><tr><td id = \"td0\" title=\"angularUnitName (Angular Unit)\">angularUnitName (Angular Unit)</td><td title=\"Degree\">Degree</td></tr><tr><td id = \"td0\" title=\"datumName (Datum)\">datumName (Datum)</td><td title=\"D_WGS_1984\">D_WGS_1984</td></tr></table></div><br>"
      ],
      "text/plain": [
       "<Extent object at 0x2cf1ad2eb20[0x2cf1ad2e9c0]>"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arcpy.FromGeohash(\"wx4g0f6f\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [],
   "source": [
    "def getExtentCenter(geohash):\n",
    "    extent = arcpy.FromGeohash(geohash)\n",
    "    extent_x = (extent.XMax + extent.XMin) / 2\n",
    "    extent_y = (extent.YMax + extent.YMin) / 2\n",
    "    pnt = arcpy.Point(extent_x, extent_y)\n",
    "    pnt_geom = arcpy.PointGeometry(pnt, arcpy.SpatialReference(4326))\n",
    "    return pnt_geom"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'POINT (116.403927 39.915087)'"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pt_tam.WKT"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'POINT (116.40409469604492 39.915132522583008)'"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "getExtentCenter(\"wx4g0f6f\").WKT"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [],
   "source": [
    "def getPrecisionLoss(s_pt,geohash):\n",
    "    s_x = s_pt.centroid.X\n",
    "    s_y = s_pt.centroid.Y\n",
    "\n",
    "    geo_pt = getExtentCenter(geohash)\n",
    "    g_x = geo_pt.centroid.X\n",
    "    g_y = geo_pt.centroid.Y\n",
    "    print(f\"X方向精度损失率：{abs((s_x-g_x)/g_x * 100)}% Y方向精度损失率：{abs((s_y-g_y)/g_y * 100)}%\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "X方向精度损失率：0.00014406369927435605% Y方向精度损失率：0.0001140484325895579%\n"
     ]
    }
   ],
   "source": [
    "getPrecisionLoss(pt_tam,\"wx4g0f6f\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "length = 1\t geohash =w\n",
      "X方向精度损失率：3.4701573333333298% Y方向精度损失率：77.40038666666666%\n",
      "length = 2\t geohash =wx\n",
      "X方向精度损失率：1.4569930158730193% Y方向精度损失率：5.386460444444445%\n",
      "length = 3\t geohash =wx4\n",
      "X方向精度损失率：0.33469802020201667% Y方向精度损失率：0.4068004678362579%\n",
      "length = 4\t geohash =wx4g\n",
      "X方向精度损失率：0.11930513826043587% Y方向精度损失率：0.1879143150183156%\n",
      "length = 5\t geohash =wx4g0\n",
      "X方向精度损失率：0.012687473412619998% Y方向精度损失率：0.02311725554944107%\n",
      "length = 6\t geohash =wx4g0f\n",
      "X方向精度损失率：0.0014712761707048963% Y方向精度损失率：0.002479352278722586%\n",
      "length = 7\t geohash =wx4g0f6\n",
      "X方向精度损失率：0.00029834828687650984% Y方向精度损失率：0.0007591423967711095%\n",
      "length = 8\t geohash =wx4g0f6f\n",
      "X方向精度损失率：0.00014406369927435605% Y方向精度损失率：0.0001140484325895579%\n",
      "length = 9\t geohash =wx4g0f6f0\n",
      "X方向精度损失率：1.502727434903506e-05% Y方向精度损失率：4.7226358924745426e-05%\n",
      "length = 10\t geohash =wx4g0f6f0p\n",
      "X方向精度损失率：1.2019233558941896e-06% Y方向精度损失率：1.8782433134582138e-07%\n",
      "length = 11\t geohash =wx4g0f6f0pd\n",
      "X方向精度损失率：5.262457870395536e-07% Y方向精度损失率：1.49212251425956e-06%\n",
      "length = 12\t geohash =wx4g0f6f0pdb\n",
      "X方向精度损失率：9.420349570630163e-08% Y方向精度损失率：2.2169027441655992e-08%\n",
      "length = 13\t geohash =wx4g0f6f0pdbq\n",
      "X方向精度损失率：4.194685481766135e-09% Y方向精度损失率：3.032931217253108e-08%\n",
      "length = 14\t geohash =wx4g0f6f0pdbqw\n",
      "X方向精度损失率：3.0575502520730765e-10% Y方向精度损失率：2.482150092795392e-09%\n",
      "length = 15\t geohash =wx4g0f6f0pdbqw7\n",
      "X方向精度损失率：2.568000381422199e-10% Y方向精度损失率：8.415769800404492e-10%\n",
      "length = 16\t geohash =wx4g0f6f0pdbqw79\n",
      "X方向精度损失率：1.1616127230424463e-10% Y方向精度损失率：1.8378121545872507e-10%\n",
      "length = 17\t geohash =wx4g0f6f0pdbqw79z\n",
      "X方向精度损失率：6.897647803659217e-12% Y方向精度损失率：2.9977486132508427e-11%\n",
      "length = 18\t geohash =wx4g0f6f0pdbqw79zq\n",
      "X方向精度损失率：2.502686371239295e-12% Y方向精度损失率：2.064957477060489e-12%\n",
      "length = 19\t geohash =wx4g0f6f0pdbqw79zq3\n",
      "X方向精度损失率：2.4416452402335256e-13% Y方向精度损失率：4.628352965825308e-13%\n",
      "length = 20\t geohash =wx4g0f6f0pdbqw79zq3d\n",
      "X方向精度损失率：1.098740358105085e-13% Y方向精度损失率：1.424108604869334e-13%\n"
     ]
    }
   ],
   "source": [
    "for i in range(1,21):\n",
    "    geohash = pt_tam.getGeohash(i)\n",
    "    print(f\"length = {i}\\t geohash ={geohash}\")\n",
    "    getPrecisionLoss(pt_tam,geohash)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.7.11 ('base')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.11"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "06b308fdbfd5979111721ebbf4de1ae2cbf405c7740d4ab5c57cb4c3e518bed6"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
